home *** CD-ROM | disk | FTP | other *** search
/ PC Electronics Plus 3 / PC Electronics Plus 3.iso / coil01 / coil.c next >
C/C++ Source or Header  |  1996-02-28  |  8KB  |  462 lines

  1. /* Main program for electrical self inductance of a coil.
  2.  *
  3.  * Program by Steve Moshier
  4.  * moshier@world.std.com
  5.  *
  6.  * Last rev: December, 1992
  7.  * Version 0.1: February, 1996 (Menu item to choose inches or centimeters)
  8.  */
  9.  
  10. double floor(), sqrt(), exp(), log(), pow();
  11. double skin(), helsol(), nagaoka(), rsol(), squaresol();
  12.  
  13. /* 0 for centimeters, 1 for inches */
  14. int INCHES = 1;
  15.  
  16. double diameter = 0.0;
  17. double length = 0.0;
  18. double dbundle = 0.0;
  19. double outer = 0.0;
  20. double frequency = 0.0;
  21. double N = 0.0;
  22. double gauge = 0.0;
  23. int geometry = 1;
  24.  
  25. #define PI 3.14159265358979323846
  26.  
  27. extern double MACHEP; /* = 2.2e-16; */
  28. extern double MAXNUM; /* = 1.7e38; */
  29.  
  30.  
  31. char str[40];
  32.  
  33. main()
  34. {
  35. double b, p, d, l, a, L, s;
  36.  
  37.  
  38. printf( "Steve Moshier's Inductance Calculator v0.1\n\n" );
  39.  
  40. loop:
  41.  
  42. printf( "\nGeometry of coil:\n1 Circular solenoidal current sheet" );
  43. printf( "\n2 Straight round wire" );
  44. printf( "\n3 N-turn circular loop\n4 Circular toroid, circular winding" );
  45. printf( "\n5 Multi-layer square solenoid (low precision)" );
  46. printf( "\n6 Circular torus ring, rectangular winding" );
  47. printf( "\n7 Multi-layer circular solenoid" );
  48. printf( "\n8 Single-layer circular solenoid of round wire" );
  49. printf( "\n9 Single-layer square solenoid" );
  50. printf( "\n10 Wire gauge calculation" );
  51. if (INCHES)
  52.   printf( "\n11 Change units to centimeters (now inches)\n");
  53. else
  54.   printf( "\n11 Change units to inches (now centimeters)\n");
  55. printf( " Choose menu item number (%d) ? ", geometry );
  56. gets( str );
  57. sscanf( str, "%d", &geometry );
  58. printf( "%d\n", geometry );
  59.  
  60.  
  61. if( geometry < 0 )
  62.     exit(0);   /* graceful exit to monitor */
  63.  
  64. if( (geometry <= 0) || (geometry > 11) )
  65.     goto operror;
  66.  
  67. if( geometry == 10 )
  68.     {
  69.     wire();
  70.     goto loop;
  71.     }
  72.  
  73. if( geometry == 11 )
  74.     {
  75.     if (INCHES)
  76.         INCHES = 0;
  77.     else
  78.         INCHES = 1;
  79.     goto loop;
  80.     }
  81.  
  82. /* Thick circular solenoid
  83.  */
  84. if( geometry == 7 )
  85.     {
  86.     getnum( "Average diameter", &diameter, 0 );
  87. getrad:
  88.     getnum( "Radial depth of winding", &dbundle, 0 );
  89.     if( dbundle > diameter )
  90.         {
  91.         printf( "Depth cannot exceed diameter. Try again.\n" );
  92.         goto getrad;
  93.         }
  94.     getnum( "Length of winding", &length, 0 );
  95.     getnum( "Total number of turns", &N, 1 );
  96.     if( INCHES )
  97.         {
  98.         d = 2.54 * diameter;
  99.         l = 2.54 * length;
  100.         a = 2.54 * dbundle;
  101.         }
  102.     else
  103.         {
  104.         d = diameter;
  105.         l = length;
  106.         a = dbundle;
  107.         }
  108.     L = rsol( 0.5*d, l, a, N );
  109.     goto done;
  110.     }
  111.  
  112. /* Circular torus ring of rectangular cross section
  113.  * Ref: Skilling 1948
  114.  */
  115. if( geometry == 6 )
  116.     {
  117.     getnum( "Inner diameter of circular torus ring", &diameter, 1 );
  118.     getnum( "Radial width of winding cross section", &dbundle, 0 );
  119.     getnum( "Height of winding cross section", &length, 0 );
  120.     getnum( "Total number of turns", &N, 0 );
  121.     if( INCHES )
  122.         {
  123.         d = 2.54 * diameter;
  124.         l = 2.54 * length;
  125.         a = 2.54 * dbundle;
  126.         }
  127.     else
  128.         {
  129.         d = diameter;
  130.         l = length;
  131.         a = dbundle;
  132.         }
  133.     d *= 0.5;
  134.     L = 2.0e-9 * N * N * l * log( 1.0 + a/d );
  135.     goto done;
  136.     }
  137.  
  138. /* Square coil, rectangular winding cross section (thickness, length).
  139.  * Ref: Grover 1922a, CRC handbook
  140.  */
  141. if( (geometry == 5) || (geometry == 9) )
  142.     {
  143.   getnum( "Side of square, to center of winding thickness", &diameter, 1 );
  144.     getnum( "Winding length", &length, 1 );
  145.     if( geometry == 5 )
  146.         {
  147.         getnum( "Winding thickness", &dbundle, 0 );
  148.         }
  149.     getnum( "Total number of turns", &N, 0 );
  150.     if( INCHES )
  151.         {
  152.         d = 2.54 * diameter;
  153.         l = 2.54 * length;
  154.         a = 2.54 * dbundle;
  155.         }
  156.     else
  157.         {
  158.         d = diameter;
  159.         l = length;
  160.         a = dbundle;
  161.         }
  162.     if( geometry == 9 )
  163.         {
  164.         L = squaresol( d, l, N );
  165.         }
  166.     else
  167.         {
  168.         if( (a+l) == 0.0 )
  169.             goto operror;
  170.         s = d/(a+l);
  171.         L = 8.e-9 * d * N * N * (log(s) + 0.2235/s + 0.726 );
  172.         }
  173.     goto done;
  174.     }
  175.  
  176. /* Circular toroid
  177.  * Ref: CRC handbook
  178.  */
  179. if( geometry == 4 )
  180.     {
  181. torrad:
  182.     getnum( "Radius distance from center of torus to center of winding",
  183.         &diameter, 0 );
  184.     getnum( "Diameter of circular winding", &length, 0 );
  185.     if( length > 2.0*diameter )
  186.         {
  187.         printf( "Diameter cannot exceed toroid diameter. Try again.\n" );
  188.         goto torrad;
  189.         }
  190.     getnum( "Total number of turns", &N, 0 );
  191.  
  192.     if( INCHES )
  193.         {
  194.         d = 2.54 * diameter;
  195.         l = 2.54 * length;
  196.         }
  197.     else
  198.         {
  199.         d = diameter;
  200.         l = length;
  201.         }
  202.  
  203.     L = 4.0e-9 * PI * N * N * (d - sqrt(d*d - 0.25*l*l));
  204.     goto done;
  205.     }
  206.  
  207.  
  208. /* Solenoid, loop, or straight wire
  209.  */
  210. if( geometry == 2 )
  211.     { /* straight wire */
  212.     diameter = 0.0;
  213.     }
  214. else
  215.     {
  216.     getnum( "Diameter of winding", &diameter, 0 );
  217.     }
  218.  
  219. if( geometry == 3 )
  220.     { /* circular loop */
  221.     length = 0.0;
  222.     }
  223. else
  224.     {
  225.     if( geometry == 2 )
  226.         getnum( "Length of wire", &length, 0 );
  227.     else
  228.         getnum( "Length of winding", &length, 0 );
  229.     }
  230.  
  231. if( (length == 0.0) && (diameter == 0.0) )
  232.     {
  233.     L = 0.0;
  234.     goto done;
  235.     }
  236.  
  237. if( geometry == 8 )
  238.     getnum( "Wire diameter", &dbundle, 1 );
  239.  
  240. if( INCHES )
  241.     {
  242.     d = 2.54 * diameter;
  243.     l = 2.54 * length;
  244.     a = 2.54 * dbundle;
  245.     }
  246. else
  247.     {
  248.     d = diameter;
  249.     l = length;
  250.     a = dbundle;
  251.     }
  252.  
  253. if( d == 0.0 )
  254.     goto straight;
  255.  
  256. getnum( "Total number of turns", &N, 0 );
  257.  
  258. if( l == 0.0 )
  259.     goto circloop;
  260.  
  261. if( geometry == 1 )
  262.     L = nagaoka( 0.5*d, l, N );
  263. else
  264.     {
  265.     if( a*N > l )
  266.         {
  267.         printf( "Wire diameter too large.\n" );
  268.         goto operror;
  269.         }
  270.     L = helsol( 0.5*d, l, a, N );
  271.     }
  272. goto done;
  273.  
  274.  
  275.  
  276.  
  277.  
  278. /* Ref: CRC handbook; Snow 1952
  279.  */
  280. circloop:
  281.  
  282. printf( "Circular loop.\n" );
  283. getnum( "Please enter diameter of wire or bundle of wires", &dbundle, 1 );
  284.  
  285. if( INCHES )
  286.     a = 2.54 * dbundle;
  287. else
  288.     a = dbundle;
  289.  
  290. p = d/a;
  291. /* For "natural" current distribution b = -1
  292.  * For uniform current distribution b = 0 (Litz wire)
  293.  */
  294. b = -1.0;
  295.  
  296. if( N <= 1.0 )
  297.     s = skin(a);
  298. else
  299.     s = 0.25;
  300.  
  301. if( a <= 0.0 )
  302.     L = MAXNUM;
  303. else
  304.     {
  305.     L = 2.e-9 * PI * N * N * d
  306.   * ( (1.0 + (2.0*b+1.0)/(8.0*p)) * log(8.0*p) - 2.0 + s
  307.   + (b-1.0)*(b-2.0/3.0)/(16.0*p*p));
  308.     }
  309. goto done;
  310.  
  311.  
  312.  
  313.  
  314.  
  315. /* Ref: CRC handbook
  316.  */
  317. straight:
  318.  
  319.  
  320. printf( "Straight piece of wire.\n" );
  321. getnum( "Please enter diameter of wire", &dbundle, 1 );
  322.  
  323. if( INCHES )
  324.     a = 2.54 * dbundle;
  325. else
  326.     a = dbundle;
  327.  
  328. L = 2.0e-9 * ( log(4.0*l/a) - 1.0 + skin(a) + 0.5*a/l );
  329.  
  330.  
  331.  
  332. done:
  333.  
  334. printf( "The inductance = %.3e henrys.\n", L );
  335.  
  336. goto loop;
  337.  
  338.  
  339. operror:
  340. printf( "? operator error\n" );
  341. goto loop;
  342.  
  343. }
  344.  
  345.  
  346.  
  347.  
  348.  
  349. /* Skin effect correction.
  350.  * This is a close empirical approximation to a table
  351.  * found in the CRC handbook.
  352.  */
  353. double skin( d )
  354. double d; /* wire diameter */
  355. {
  356. double s;
  357.  
  358. getnum( "Frequency in Hz, for skin effect", &frequency, 0 );
  359. if( frequency <= 0.0 )
  360.     return( 0.25 );
  361.  
  362. s = 0.1071 * d * sqrt(frequency);
  363. if( s > 100.0 )
  364.     {
  365.     s = 7.088/s;
  366.     }
  367. else
  368.     {
  369.     s = 0.00546 * pow(s,5.0);
  370.     s = 0.25 * pow( 1.0+s, -0.2 );
  371.     }
  372. return(s);
  373. }
  374.  
  375.  
  376.  
  377. /* Subroutine to get value entered on keyboard
  378.  * Displays previous value and updates only if a new value is entered.
  379.  */
  380. getnum( s, pd, zflag )
  381. char *s;
  382. double *pd;
  383. int zflag;
  384. {
  385. double t;
  386.  
  387. gloop:
  388. printf( "%s (%.5lf) ? ", s, *pd );
  389. gets(str);
  390.  
  391. if( (str[0] == '\0') && (*pd <= 0.0) )
  392.     {
  393.     t = *pd;
  394.     goto tests;
  395.     }
  396.  
  397. if( str[0] != '\0' )
  398.     {
  399.     sscanf( str, "%lf", &t );
  400. tests:
  401.     if( zflag >= 0 )
  402.     {
  403.     if( t < 0.0 )
  404.         {
  405.         printf( " ? Negative value not allowed; try again.\n" );
  406.         goto gloop;
  407.         }
  408.     if( zflag )
  409.         {
  410.         if( t == 0.0 )
  411.             {
  412.             printf( " ? Zero value not allowed; try again.\n" );
  413.             goto gloop;
  414.             }
  415.         }
  416.     }
  417.     *pd = t;
  418.     }
  419. /* Verify the value that will be used */
  420. if( *pd > 1.0e4 )
  421.     printf( "%.5e\n", *pd );
  422. else
  423.     printf( "%.5lf\n", *pd );
  424. }
  425.  
  426.  
  427. wire()
  428. {
  429. double b, c, d;
  430.  
  431.  
  432. getnum( "American Wire Gauge (B&S) number", &gauge, -1 );
  433.  
  434. d = 0.32485 * exp( -0.11594 * gauge );
  435.  
  436. if( INCHES )
  437.     printf( "Wire diameter = %.3e inches.\n", d );
  438. else
  439.     printf( "Wire diameter = %.3e centimeters.\n", 2.54*d );
  440. d *= 2.54; /* convert to centimeters */
  441. getnum( "Coil length", &length, 0 );
  442. getnum( "Winding thickness", &dbundle, 0 );
  443. if( INCHES )
  444.     {
  445.     b = 2.54 * length;
  446.     c = 2.54 * dbundle;
  447.     }
  448. else
  449.     {
  450.     b = length;
  451.     c = dbundle;
  452.     }
  453. N = 1.0;
  454. b = floor( b/d );
  455. if( b > 0.0 )
  456.     N = b;
  457. c = floor( c/d );
  458. if( c > 0.0 )
  459.     N *= c;
  460. printf( "%.0lf turns will fit in this space.\n", N );
  461. }
  462.